package com.common.atom.seal.util;

import com.common.atom.seal.param.DoubleRowSealParam;
import com.common.atom.seal.param.SingleRowSealParam;
import com.sun.imageio.plugins.common.ImageUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * description: ImageUtils <br>
 * date: 2023/4/13  <br>
 * author: zss <br>
 * version: 1.0.0 <br>
 */
public class ImageUtils {


    private static final Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    public static final int COLOR_MODE_RED = 1;
    public static final int COLOR_MODE_GREEN = 2;
    public static final int COLOR_MODE_BLUE = 3;
    public static final int COLOR_MODE_BLACK = 4;

    // 透明切割阈值
    static final int STARDER_ARGB = 210;
    static final int STARDER_ARGB_LOW = 130;
    static final int STARDER_ARGB_SAMPLING_DISTANCE = 5;

    private static void drawTopAndBottomText(Graphics2D g2, String text, int textType, int[] fontSizeMapping,
                                             int type, int radius, int charInterWidth) {
        text = text.replace("(", "（");
        text = text.replace(")", "）");

        final int CENTERX = 300;
        final int CENTERY = 300;

        // 根据输入字符串得到字符数组

        String[] texts = new String[text.length()];

        for (int i = 0; i < text.length(); i++) {
            texts[i] = text.substring(i, i + 1);
        }
        // 输入的字数
        int ilength = texts.length;

        // 设置字体属性
        // 14个字60 840
        // 18个字50 900
        // 22个字42 924

        int fontsize = fontSizeMapping[ilength];

        Font f = null;
        if (type == 2) {
            f = new Font("SimHei", Font.PLAIN, fontsize);
        } else if (type == 3) {
            f = new Font("SimSun", Font.BOLD, fontsize);
        } else {
            f = new Font("Microsoft YaHei", Font.PLAIN, fontsize);
        }

        FontRenderContext context = g2.getFontRenderContext();

        Rectangle2D bounds = f.getStringBounds(text, context);

        // 字符宽度＝字符串长度/字符数

        double char_interval = (bounds.getWidth() / ilength + charInterWidth);

        double ascent = 0;
        if (textType == 1) {
            ascent = -bounds.getY();// 上坡度
        } else {
            ascent = bounds.getY();// 下坡度
        }

        int first = 0, second = 0;
        boolean odd = false;

        if (ilength % 2 == 1) {
            first = (ilength - 1) / 2;
            odd = true;
        } else {
            first = (ilength) / 2 - 1;
            second = (ilength) / 2;
            odd = false;
        }

        double radius2 = radius - ascent;

        double x0 = CENTERX;

        double y0 = CENTERY - radius + ascent;

        // 旋转角度

        double a = 2 * Math.asin(char_interval / (2 * radius2));

        if (odd) {

            g2.setFont(f);

            g2.drawString(texts[first], (float) (x0 - char_interval / 2), (float) y0);

            // 中心点的右边

            for (int i = first + 1; i < ilength; i++) {

                double aa = (i - first) * a;

                double ax = radius2 * Math.sin(aa);

                double ay = radius2 - radius2 * Math.cos(aa);

                AffineTransform transform = AffineTransform.getRotateInstance(aa);

                Font f2 = f.deriveFont(transform);

                g2.setFont(f2);

                g2.drawString(texts[i], (float) (x0 + ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));

            }

            // 中心点的左边

            for (int i = first - 1; i > -1; i--) {

                double aa = (first - i) * a;

                double ax = radius2 * Math.sin(aa);

                double ay = radius2 - radius2 * Math.cos(aa);

                AffineTransform transform = AffineTransform.getRotateInstance(-aa);
                Font f2 = f.deriveFont(transform);
                g2.setFont(f2);
                g2.drawString(texts[i], (float) (x0 - ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
            }

        } else {

            // 中心点的右边

            for (int i = second; i < ilength; i++) {

                double aa = (i - second + 0.5) * a;

                double ax = radius2 * Math.sin(aa);

                double ay = radius2 - radius2 * Math.cos(aa);

                AffineTransform transform = AffineTransform.getRotateInstance(aa);

                Font f2 = f.deriveFont(transform);

                g2.setFont(f2);

                g2.drawString(texts[i], (float) (x0 + ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));

            }

            // 中心点的左边

            for (int i = first; i > -1; i--) {

                double aa = (first - i + 0.5) * a;

                double ax = radius2 * Math.sin(aa);

                double ay = radius2 - radius2 * Math.cos(aa);

                AffineTransform transform = AffineTransform.getRotateInstance(-aa);
                Font f2 = f.deriveFont(transform);
                g2.setFont(f2);
                g2.drawString(texts[i], (float) (x0 - ax - char_interval / 2 * Math.cos(aa)), (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));

            }

        }
    }


    /**
     * 从右到左双行人名章
     * 这是之前的代码
     *
     * @throws Exception
     */
//    public static byte[] makeSquareStamp(DoubleRowSealParam sealParam)
//            throws FileNotFoundException, IOException {
//
//        BufferedImage image = null;
//
//        int fontSize = 80;
//        int fontSpace = 100;
//        int stampHeight = 200;
//        int lineWidth = 5;
//        stampHeight = stampHeight + lineWidth * 2;
//
//        Color color = ColorUtil.getColor(sealParam.getColor(), sealParam.getAlpha());
//
//        if (StringUtils.isBlank(sealParam.getName())) {
//            throw new IOException("图章姓名不能为空！");
//        }
//        String newMessage = null;
//
//        if (sealParam.getName().length() == 2) {
//
//            newMessage = sealParam.getName() + "之印";
//
//        } else if (sealParam.getName().length() % 2 == 1) {
//
//            newMessage = sealParam.getName() + "印";
//
//        } else {
//            newMessage = sealParam.getName();
//        }
//
//        int stampWidth = fontSpace * ((int) Math.floor(newMessage.length() * 0.5f + 0.5f));
//        stampWidth = stampWidth + lineWidth * 2;
//        // String
//        // templatePath=ImageUtil.class.getResourceAsStream("s"+templateType+".png");
//        // String
//        // templatePath=ImageUtil.class.getResource("").getPath()+"s"+templateType+".png";
//
//        ByteArrayInputStream bais = new ByteArrayInputStream(getRect(stampWidth, stampHeight, lineWidth, color));
//
//        image = ImageIO.read(bais);
//
//        Graphics2D g2 = image.createGraphics();// 得到图形上下文
//
//        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 平滑
//        g2.setColor(color);
//
//
//        Font f = null;
//        if (sealParam.getSealFontType() == 1) {
//            f = new Font("Microsoft YaHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
//        } else if (sealParam.getSealFontType() == 2) {
//            f = new Font("SimHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
//        } else if (sealParam.getSealFontType() == 3) {
//            f = new Font("SimSun", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
//        } else if (sealParam.getSealFontType() == 4) {
//            f = new Font("华文行楷", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
//        } else if (sealParam.getSealFontType() == 5) {
//            f = new Font("方正舒体", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
//        } else {
//            f = new Font("Microsoft YaHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
//        }
//
//        // 设置字体
//
//        g2.setFont(f);// 写入签名
//
//        char[] charArray = newMessage.toCharArray();
//
//        for (int i = 0; i < charArray.length; i++) {
//
//            int fontX = stampWidth - lineWidth - (i / 2 + 1) * fontSpace + (fontSpace - fontSize) / 2;
//
//            int fontY = (i % 2) * fontSpace + lineWidth + fontSize;
//
//            g2.drawString(new String(new char[]{charArray[i]}), fontX, fontY); // 写文字
//
//        }
//
//
//        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//        int width = sealParam.getDiameter();
//        int height = sealParam.getDiameter();
//        BufferedImage buffImg = new BufferedImage(width, height, 6);
//        buffImg.getGraphics().drawImage(image.getScaledInstance(width, height, 4), 0, 0, null);
//
//        ImageIO.write(buffImg, "png", byteArrayOutputStream);
//
//        return byteArrayOutputStream.toByteArray();
//
//    }
//
    public static Font CreateFont(int fontType, int fontSize) {
        Font f = null;
        if (fontType == 1) {
            f = new Font("Microsoft YaHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (fontType == 2) {
            f = new Font("SimHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (fontType == 3) {
            f = new Font("SimSun", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (fontType == 4) {
            f = new Font("华文行楷", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (fontType == 5) {
            f = new Font("方正舒体", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (fontType == 6) {
            f = new Font("楷体", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else {
            //默认是宋体
            f = new Font("SimSun", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        }
        return f;
    }

    public static void setRenderingHint(Graphics2D graphics2d) {

        graphics2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        graphics2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
        graphics2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        graphics2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        graphics2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        graphics2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

    }

    public static FontMetrics createFontMetrics(Font font) {
        BufferedImage bufferedIamge = new BufferedImage(1, 1, 2);
        Graphics2D graphics2d = getSmoothGraphics2D(bufferedIamge);
        graphics2d.setFont(font);
        return graphics2d.getFontMetrics();
    }

    public static Graphics2D getSmoothGraphics2D(BufferedImage bufferedImage) {
        Graphics2D graphics2d = (Graphics2D) bufferedImage.getGraphics();
        //graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        setRenderingHint(graphics2d);
        return graphics2d;
    }

    /***
     * 新的双排章接口, 解决电子合同,黄祖清的需求
     * @param sealParam
     * @return
     * @throws FileNotFoundException
     * @throws IOException
     */

    public static byte[] makeDoubleRowSeal(DoubleRowSealParam sealParam) throws IOException {
        BufferedImage image = null;
        int fontSize = 80;
        int fontSpace = 90;
        //默认的章的高度
        //int stampHeight = 200;
        //行的宽度
        int lineWidth = sealParam.getLineWidth() == 0.0f ? 5 : Math.round(sealParam.getLineWidth());
        //这是假定的 矩形
        //
        Font textFont = CreateFont(sealParam.getFontType(), fontSize);
        //
        FontMetrics fontMetrics = createFontMetrics(textFont);
        int wHeight = fontMetrics.getHeight();

        Color color = ColorUtils.getColor(sealParam.getColor(), sealParam.getAlpha());
        if (StringUtils.isBlank(sealParam.getName())) {
            throw new IllegalArgumentException("图章姓名不能为空！");
        }
        String newMessage = null;
        if (sealParam.getName().length() == 2) {
            newMessage = sealParam.getName() + "之印";
        } else if (sealParam.getName().length() % 2 == 1) {
            newMessage = sealParam.getName() + "印";
        } else {
            newMessage = sealParam.getName();
        }

        int stampWidth = fontSpace * ((int) Math.floor(newMessage.length() * 0.5f + 0.5f));
        stampWidth = stampWidth + lineWidth * 2;


        ByteArrayInputStream bais = new ByteArrayInputStream(getRect(stampWidth, stampWidth, lineWidth, color));
        image = ImageIO.read(bais);
        Graphics2D g2 = image.createGraphics();
        // 得到图形上下文
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 平滑
        g2.setColor(color);
        Font f = null;
        if (sealParam.getFontType() == 1) {
            f = new Font("Microsoft YaHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 2) {
            f = new Font("SimHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 3) {
            f = new Font("SimSun", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 4) {
            f = new Font("华文行楷", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 5) {
            f = new Font("方正舒体", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 6) {
            f = new Font("楷体", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else {
            f = new Font("Microsoft YaHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        }
        // 设置字体
        g2.setFont(f);
        // 写入签名
        char[] charArray = newMessage.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            int fontX = stampWidth - lineWidth - (i / 2 + 1) * fontSpace + (fontSpace - fontSize) / 2;
            if (i / 2 == 0) {
                fontX -= 8;
            } else {
                fontX += 8;
            }
            //int fontX = stampWidth - lineWidth - (i / 2 + 1) * wHeight + (wHeight - fontSize) / 2;
            int fontY = (i % 2) * fontSpace + lineWidth + fontSize + (i % 2 == 0 ? 10 : -10);
            //int fontY = (i % 2) * wHeight + lineWidth + fontSize;
            // 写文字
            g2.drawString(new String(new char[]{charArray[i]}), fontX, fontY);

        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int width = sealParam.getDiameter();
        int height = sealParam.getDiameter();
        BufferedImage buffImg = new BufferedImage(width, height, 6);
        buffImg.getGraphics().drawImage(image.getScaledInstance(width, height, 4), 0, 0, null);

        ImageIO.write(buffImg, "png", byteArrayOutputStream);

        return byteArrayOutputStream.toByteArray();

    }


    public static Dimension getNameDimension(String message, FontMetrics metrics) {
        int hgt = metrics.getHeight();
        int adv = metrics.stringWidth(message);
        Dimension size = new Dimension(adv + 4, hgt + 2);
        return size;
    }

    /**
     * 从左到右单行人名章
     * sealParam
     *
     * @throws Exception
     */
    public static byte[] makeSingleRowSeal(SingleRowSealParam sealParam) throws IOException {
        BufferedImage image = null;
        int fontSize = sealParam.getFontSize();
        int lineWidth = 1;

        Color color = ColorUtils.getColor(sealParam.getColor(), sealParam.getAlpha());

        Font f = null;
        if (sealParam.getFontType() == 1) {
            f = new Font("Microsoft YaHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 2) {
            f = new Font("SimHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 3) {
            f = new Font("SimSun", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 4) {
            f = new Font("华文行楷", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else if (sealParam.getFontType() == 5) {
            f = new Font("方正舒体", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        } else {
            f = new Font("Microsoft YaHei", Font.LAYOUT_LEFT_TO_RIGHT, fontSize);
        }

        //字体缩放
        f = SealUtils.scaleFont(f, 1, sealParam.getScaling());
        String newMessage = sealParam.getName();
        FontMetrics metrics = SealUtils.createFontMetrics(f);

        Dimension size = getNameDimension(newMessage, metrics);

        int stampHeight = metrics.getHeight() + lineWidth * 2;
        int stampWidth = metrics.stringWidth(newMessage) + lineWidth * 4;

        if (size != null) {
            stampHeight = stampHeight < size.height ? size.height : stampHeight;
            stampWidth = stampWidth < size.width ? size.width : stampWidth;
        }

        ByteArrayInputStream output;
        //根据像素 点 来设置空间大小
        if (sealParam.getFrame() == 1) {
            output = new ByteArrayInputStream(getRect(stampWidth, stampHeight, lineWidth, color));
        } else {
            //没有边框则将边框颜色置为白色，透明化后将无边框
            output = new ByteArrayInputStream(getRect(stampWidth, stampHeight, 0, new Color(0, 0, 0)));
        }

        image = ImageIO.read(output);

        // 得到图形上下文
        Graphics2D g2 = image.createGraphics();

        // 平滑
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(color);


        // 设置字体
        // 写入签名
        g2.setFont(f);
        //size = getNameDimension(newMessage, g2.getFontMetrics(f));

        char[] charArray = newMessage.toCharArray();

        int fontY = metrics.getAscent();
        int fontX = lineWidth * 2;
//        for (int i = 0; i < charArray.length; i++) {
//            // 写文字
//            g2.drawString(new String(new char[]{charArray[i]}), fontX, fontY);
//            fontX += fontSize;
//        }

        g2.drawString(newMessage, fontX, fontY);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        ImageIO.write(image, "png", byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }


    /**
     * 画方形边框
     *
     * @param width
     * @param height
     * @param lineWidth
     * @param color
     * @return
     * @throws IOException
     */
    public static byte[] getRect(int width, int height, int lineWidth, Color color) throws IOException {

        BufferedImage rectImage = new BufferedImage(width, height, 3);
        Graphics2D g2d = rectImage.createGraphics();

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(color);


        g2d.fillRect(0, 0, width, lineWidth);
        g2d.fillRect(0, 0, lineWidth, height);
        g2d.fillRect(width - lineWidth, 0, lineWidth, height);
        g2d.fillRect(0, height - lineWidth, width, lineWidth);


        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write(rectImage, "png", out);
        return out.toByteArray();
    }


    // 获得指定文件的byte数组
    public static byte[] getBytes(String filePath) {
        byte[] buffer = null;
        try (FileInputStream fis = new FileInputStream(new File(filePath))) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return buffer;
    }

    // 根据byte数组，生成文件
    public static void saveImgFile(byte[] bfile, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {

            file = new File(fileName);

            if (!file.exists() && file.isDirectory()) {
                file.mkdirs();
            } else if (!file.isDirectory()) {
                File parentDir = file.getParentFile();
                if (!parentDir.exists()) {
                    parentDir.mkdirs();
                }
            }

            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e1) {
                    logger.error(e1.getMessage(), e1);
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    logger.error(e1.getMessage(), e1);
                }
            }
        }
    }

    //设置透明度
    public static BufferedImage setAlpha(BufferedImage bufferedImage2, int alpha) {

        BufferedImage bufferedImage = new BufferedImage(bufferedImage2.getWidth(), bufferedImage2.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
        g2D.drawImage(bufferedImage2, 0, 0, null);

        //判读透明度是否越界
        if (alpha < 0) {
            alpha = 0;
        } else if (alpha > 10) {
            alpha = 10;
        }
        for (int h = 0; h < bufferedImage.getHeight(); h++) {
            for (int w = 0; w < bufferedImage.getWidth(); w++) {
                int a = bufferedImage.getRGB(w, h);
                if (a != 0) {
                    a = ((alpha * 255 / 10) << 24) | (a & 0x00ffffff);
                }
                bufferedImage.setRGB(w, h, a);
            }
        }
        g2D.drawImage(bufferedImage, 0, 0, null);
        return bufferedImage;
    }

}
